package cn.kys.common.utils;


/*import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;*/
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.MultiPolygon;
import org.locationtech.jts.geom.Polygon;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;
import org.gdal.gdal.gdal;
import org.gdal.ogr.*;
import org.geotools.geometry.jts.JTSFactoryFinder;

import java.util.*;

public class ShpReader {

    public static void ReadVectorFile(String strVectorFile) {
        //String strVectorFile = "F:\\Work\\OGR测试数据\\beijing.shp";
        // 注册所有的驱动
        ogr.RegisterAll();
        // 为了支持中文路径，请添加下面这句代码
        gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
        // 为了使属性表字段支持中文，请添加下面这句
        gdal.SetConfigOption("SHAPE_ENCODING", "");
        //打开数据
        DataSource ds = ogr.Open(strVectorFile, 0);
        if (ds == null) {
            System.out.println("打开文件【" + strVectorFile + "】失败！");
            return;
        }
        System.out.println("打开文件【" + strVectorFile + "】成功！");
        // 获取该数据源中的图层个数，一般shp数据图层只有一个，如果是mdb、dxf等图层就会有多个
        int iLayerCount = ds.GetLayerCount();
        // 获取第一个图层
        Layer oLayer = ds.GetLayerByIndex(0);
        if (oLayer == null) {
            System.out.println("获取第0个图层失败！\n");
            return;
        }
        // 对图层进行初始化，如果对图层进行了过滤操作，执行这句后，之前的过滤全部清空
        oLayer.ResetReading();
        // 通过属性表的SQL语句对图层中的要素进行筛选，这部分详细参考SQL查询章节内容
        //oLayer.SetAttributeFilter("\"NAME99\"LIKE \"北京市市辖区\"");
        // 通过指定的几何对象对图层中的要素进行筛选
        //oLayer.SetSpatialFilter();
        // 通过指定的四至范围对图层中的要素进行筛选
        //oLayer.SetSpatialFilterRect();
        // 获取图层中的属性表表头并输出
        System.out.println("属性表结构信息：");
        FeatureDefn oDefn = oLayer.GetLayerDefn();
        int iFieldCount = oDefn.GetFieldCount();
        for (int iAttr = 0; iAttr < iFieldCount; iAttr++) {
            FieldDefn oField = oDefn.GetFieldDefn(iAttr);
            System.out.println(oField.GetNameRef() + ": " +
                    oField.GetFieldTypeName(oField.GetFieldType()) + "(" +
                    oField.GetWidth() + "." + oField.GetPrecision() + ")");
        }
        // 输出图层中的要素个数
        System.out.println("要素个数 = " + oLayer.GetFeatureCount(0));
        Feature oFeature = null;
        // 下面开始遍历图层中的要素
        while ((oFeature = oLayer.GetNextFeature()) != null) {
            System.out.println("当前处理第" + oFeature.GetFID() + "个:\n属性值：");
            // 获取要素中的属性表内容
            for (int iField = 0; iField < iFieldCount; iField++) {
                FieldDefn oFieldDefn = oDefn.GetFieldDefn(iField);
                int type = oFieldDefn.GetFieldType();
                switch (type) {
                    case ogr.OFTString:
                        System.out.println(oFeature.GetFieldAsString(iField) + "\t");
                    break;
                    case ogr.OFTReal:
                        System.out.println(oFeature.GetFieldAsDouble(iField) + "\t");
                    break;
                    case ogr.OFTInteger:
                        System.out.println(oFeature.GetFieldAsInteger(iField) + "\t");
                    break;
                    default:
                        System.out.println(oFeature.GetFieldAsString(iField) + "\t");
                        break;
                }
            }
            // 获取要素中的几何体
            Geometry oGeometry = oFeature.GetGeometryRef();
            // 为了演示，只输出一个要素信息
            System.out.println(oGeometry.Area() + "\t");
            System.out.println(oGeometry.Boundary().GetX() + "\t");
            break;
        }
        System.out.println("数据集关闭！");
    }

    public static List importShp(String strVectorFile) {
        List sqlList = new ArrayList();
        //String strVectorFile = "F:\\Work\\OGR测试数据\\beijing.shp";
        // 注册所有的驱动
        ogr.RegisterAll();
        // 为了支持中文路径，请添加下面这句代码
        gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
        // 为了使属性表字段支持中文，请添加下面这句
        gdal.SetConfigOption("SHAPE_ENCODING", "CP936");
        //打开数据
        DataSource ds = ogr.Open(strVectorFile, 0);
        if (ds == null) {
            System.out.println("打开文件【" + strVectorFile + "】失败！");
            return null;
        }
        System.out.println("打开文件【" + strVectorFile + "】成功！");
        // 获取该数据源中的图层个数，一般shp数据图层只有一个，如果是mdb、dxf等图层就会有多个
        int iLayerCount = ds.GetLayerCount();
        // 获取第一个图层
        Layer oLayer = ds.GetLayerByIndex(0);
        if (oLayer == null) {
            System.out.println("获取第0个图层失败！\n");
            return null;
        }
        // 对图层进行初始化，如果对图层进行了过滤操作，执行这句后，之前的过滤全部清空
        oLayer.ResetReading();
        // 通过属性表的SQL语句对图层中的要素进行筛选，这部分详细参考SQL查询章节内容


        System.out.println("属性表结构信息：");
        FeatureDefn oDefn = oLayer.GetLayerDefn();
        int iFieldCount = oDefn.GetFieldCount();
        // 输出图层中的要素个数
        System.out.println("要素个数 = " + oLayer.GetFeatureCount(0));
        Feature oFeature = null;
        // 下面开始遍历图层中的要素
        while ((oFeature = oLayer.GetNextFeature()) != null) {
            System.out.println("当前处理第" + oFeature.GetFID() + "个:\n属性值：");
            // 获取要素中的属性表内容
            Map map = new HashMap();
            for (int iField = 0; iField < iFieldCount; iField++) {
                FieldDefn oFieldDefn = oDefn.GetFieldDefn(iField);
                String fieldName = oFieldDefn.GetName();

                int type = oFieldDefn.GetFieldType();
                switch (type) {
                    case ogr.OFTString:
                        map.put(fieldName,oFeature.GetFieldAsString(iField));
                        System.out.println(fieldName+":"+oFeature.GetFieldAsString(iField) + "\t");
                        break;
                    case ogr.OFTReal:
                        map.put(fieldName,oFeature.GetFieldAsString(iField));
                        System.out.println(fieldName+":"+oFeature.GetFieldAsDouble(iField) + "\t");
                        break;
                    case ogr.OFTInteger:
                        map.put(fieldName,oFeature.GetFieldAsString(iField));
                        System.out.println(fieldName+":"+oFeature.GetFieldAsInteger(iField) + "\t");
                        break;
                    default:
                        map.put(fieldName,oFeature.GetFieldAsString(iField));
                        System.out.println(fieldName+":"+oFeature.GetFieldAsString(iField) + "\t");
                        break;
                }

            }

            String keys = "";
            String values = "";
            Iterator it = map.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry entry = (Map.Entry) it.next();
                Object key = entry.getKey();
                Object value = entry.getValue();
                keys += ","+key;
                values += ","+value;

            }
            // 获取要素中的几何体

            Geometry oGeometry = oFeature.GetGeometryRef();
            String wkt = oGeometry.ExportToWkt();

            MultiPolygon mPoly = null;
            try {
                GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory( null );
                WKTReader reader = new WKTReader( geometryFactory );
                Polygon p = (Polygon) reader.read(wkt);
                GeometryFactory gf = new GeometryFactory();

                if (p instanceof Polygon){
                    Polygon[] polys = new Polygon[1];
                    polys[0] = p;
                    mPoly = gf.createMultiPolygon(polys);
                }
                System.out.println(mPoly.toString());

               /* //坐标转换
                CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326");
                CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:4530");

                MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, false);

                com.vividsolutions.jts.geom.Geometry geometry = JTS.transform(mPoly, transform);
                map.put("geom4326",geometry.toString());*/
            } catch (Exception e) {
                e.printStackTrace();
            }
            map.put("geom",mPoly.toString());

            sqlList.add(map);

        }

        //ds.ReleaseResultSet(oLayer);
        ds.FlushCache();

        System.out.println("数据集关闭！");
        return sqlList;
    }

    public static List importVectorFile(String strVectorFile) {
        List sqlList = new ArrayList();
        //String strVectorFile = "F:\\Work\\OGR测试数据\\beijing.shp";
        // 注册所有的驱动
        ogr.RegisterAll();
        // 为了支持中文路径，请添加下面这句代码
        gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
        // 为了使属性表字段支持中文，请添加下面这句
        gdal.SetConfigOption("SHAPE_ENCODING", "");
        //打开数据
        DataSource ds = ogr.Open(strVectorFile, 0);
        if (ds == null) {
            System.out.println("打开文件【" + strVectorFile + "】失败！");
            return null;
        }
        System.out.println("打开文件【" + strVectorFile + "】成功！");
        // 获取该数据源中的图层个数，一般shp数据图层只有一个，如果是mdb、dxf等图层就会有多个
        int iLayerCount = ds.GetLayerCount();
        // 获取第一个图层
        Layer oLayer = ds.GetLayerByIndex(0);
        if (oLayer == null) {
            System.out.println("获取第0个图层失败！\n");
            return null;
        }
        // 对图层进行初始化，如果对图层进行了过滤操作，执行这句后，之前的过滤全部清空
        oLayer.ResetReading();
        // 通过属性表的SQL语句对图层中的要素进行筛选，这部分详细参考SQL查询章节内容


        System.out.println("属性表结构信息：");
        FeatureDefn oDefn = oLayer.GetLayerDefn();
        int iFieldCount = oDefn.GetFieldCount();
        // 输出图层中的要素个数
        System.out.println("要素个数 = " + oLayer.GetFeatureCount(0));
        Feature oFeature = null;
        // 下面开始遍历图层中的要素
        while ((oFeature = oLayer.GetNextFeature()) != null) {
            System.out.println("当前处理第" + oFeature.GetFID() + "个:\n属性值：");
            // 获取要素中的属性表内容
            Map map = new HashMap();
            for (int iField = 0; iField < iFieldCount; iField++) {
                FieldDefn oFieldDefn = oDefn.GetFieldDefn(iField);
                String fieldName = oFieldDefn.GetName();

                int type = oFieldDefn.GetFieldType();
                switch (type) {
                    case ogr.OFTString:
                        map.put(fieldName,"'"+oFeature.GetFieldAsString(iField)+"'");
                        System.out.println(fieldName+":"+oFeature.GetFieldAsString(iField) + "\t");
                        break;
                    case ogr.OFTReal:
                        map.put(fieldName,oFeature.GetFieldAsString(iField));
                        System.out.println(fieldName+":"+oFeature.GetFieldAsDouble(iField) + "\t");
                        break;
                    case ogr.OFTInteger:
                        map.put(fieldName,oFeature.GetFieldAsString(iField));
                        System.out.println(fieldName+":"+oFeature.GetFieldAsInteger(iField) + "\t");
                        break;
                    default:
                        map.put(fieldName,oFeature.GetFieldAsString(iField));
                        System.out.println(fieldName+":"+oFeature.GetFieldAsString(iField) + "\t");
                        break;
                }

            }

            String keys = "";
            String values = "";
            Iterator it = map.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry entry = (Map.Entry) it.next();
                Object key = entry.getKey();
                Object value = entry.getValue();
                keys += ","+key;
                values += ","+value;

            }
            // 获取要素中的几何体

            Geometry oGeometry = oFeature.GetGeometryRef();
            String wkt = oGeometry.ExportToWkt();

            MultiPolygon mPoly = null;
            try {
                GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory( null );
                WKTReader reader = new WKTReader( geometryFactory );
                Polygon p = (Polygon) reader.read(wkt);
                GeometryFactory gf = new GeometryFactory();

                if (p instanceof Polygon){
                    Polygon[] polys = new Polygon[1];
                    polys[0] = p;
                    mPoly = gf.createMultiPolygon(polys);
                }
                System.out.println(mPoly);
            } catch (ParseException e) {
                e.printStackTrace();
            }

            String geom_text = "st_geomfromtext('"+mPoly+"'"+",4326)";


            keys = keys.substring(1,keys.length());
            keys = keys+",geom";
            values = values.substring(1,values.length());
            values = values+","+geom_text;
            System.out.println("key=" + keys + " value=" + values);

            String sql = "INSERT INTO public.ksdq_tdql_4326("+keys+")\n" +
                    " VALUES ("+values+")";
            sqlList.add(sql);
            //组装sql
            /*INSERT INTO public.ksdq_tdql_4326(
                    gid, objectid, total_area, land_type, shape_leng, shape_area, uuid, qsxz, cbsj, sfkly, landid, sfjbnt, zldwdm, zldwmc, tbmj, tbmjmu, tbmjgq, tbmjgl, geom)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);*/

            /*Geometry oGeometry = oFeature.GetGeometryRef();
            // 为了演示，只输出一个要素信息
            System.out.println(oGeometry.Area() + "\t");
            System.out.println(oGeometry.Boundary().GetX() + "\t");*/
            break;
        }

        ds.FlushCache();
        System.out.println("数据集关闭！");
        return sqlList;
    }
}
